import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import com.sun.org.apache.bcel.internal.generic.NEW;

import sun.security.provider.certpath.AdjacencyList;

// Nikolas Wolfe
// CNT 4007
// Distance Algorithm

public class Node
{
	private static final AtomicInteger uniqueId = new AtomicInteger(0);
	private final int id;
	private HashMap<Integer, Integer> adjacenyList;
	private List<Node> nodes;
	
	public Node()
	{
		this.id = uniqueId.getAndIncrement();
	}
	
	public void supplyNodes( List<Node> nodes )
	{
		this.nodes = nodes;
	}
	
	public void setAdjacencies( List<String> adjacencies )
	{
		this.adjacenyList = new HashMap<Integer, Integer>();
		for( String s : adjacencies )
		{
			String[] valuePair = s.split(",");
			int node = Integer.parseInt( valuePair[0] );
			int distance = Integer.parseInt( valuePair[1] );
			adjacenyList.put(node, distance);
		}
	}
	
	public synchronized int getDistanceToNode( Node node, int assumedDistance )
	{
		// if not infinite distance... return value
		int distance = assumedDistance;
		if( assumedDistance < 999 )
		{
			return adjacenyList.get( node.getUniqueId() );
		}
		else 
		{
			for( Node i : nodes )
			{
				distance = queryNeighborsTable( i );
				if( distance < 999 ) 
				{
					distance += i.getDistanceToNode( node, distance );
					break;
				}
			}
		}
		return distance;
	}
	
	// returns the current distance value held by a neighbor for a node
	public synchronized int queryNeighborsTable( Node n )
	{
		return adjacenyList.get( n.getUniqueId() );
	}
	
	private void populateDistanceInformation()
	{
		for( Node n : nodes )
		{
			int shortestPath = adjacenyList.get( n.getUniqueId() );
			int newPath = n.getDistanceToNode( this, shortestPath );
			if( newPath < shortestPath )
			{
				adjacenyList.put( n.getUniqueId(), newPath );
			}
		}
	}
	
	public int getUniqueId()
	{
		return id;
	}

	public void printAdjacencyTable()
	{
		populateDistanceInformation();
		System.out.println("Node " + getUniqueId() );
		for( Node i : nodes )
		{
			System.out.println( adjacenyList.toString() );
		}
		System.out.println();
	}
}